package midend.IR_Optimizer;

import midend.IR_Instruction.*;
import midend.IR_Value.IR_BaseBlock;
import midend.IR_Value.IR_FuncBlock;
import midend.IR_Value.IR_Int_Value;
import midend.IR_Value.IR_Value;

import java.util.*;

public class BrCmp_Opt implements IR_Opt {
    //针对跳转的if语句简化
    @Override
    public void Optimize(IR_FuncBlock functionBlock) {
        for (IR_BaseBlock bb : functionBlock.get_bb_List()) {
            List<Instruction> instructions = bb.get_Instruction_List();
            Iterator<Instruction> it = instructions.iterator();
            List<Integer> toRemove = new ArrayList<>();

            while (it.hasNext()) {
                Instruction instruction = it.next();
                int currentIndex = instructions.indexOf(instruction);

                if (instruction instanceof Cond_Instruction) {
                    if (currentIndex + 3 < instructions.size() && instructions.get(currentIndex + 1) instanceof Zext_Instruction
                    && instructions.get(currentIndex + 2) instanceof Cond_Instruction) {
                            if ((instructions.get(currentIndex + 2).get_op().get(1) != null
                                    && instructions.get(currentIndex + 2).get_op().get(1).get_ValueName().equals("0"))
                                    || (instructions.get(currentIndex + 2).get_op().get(2) != null
                                    && instructions.get(currentIndex + 2).get_op().get(2).get_ValueName().equals("0"))) {
                                if (instructions.get(currentIndex + 3) instanceof Branch_Instruction) {
                                    IR_Value var = instruction.get_op().get(0);
                                    Instruction branchInstruction = instructions.get(currentIndex + 3);
                                    branchInstruction.set_Op(0, var);
                                    toRemove.add(currentIndex + 1);
                                    toRemove.add(currentIndex + 2);
                                }
                            }
                        }
                    }
                }

            for (int i = toRemove.size() - 1; i >= 0; i--) {
                instructions.remove((int) toRemove.get(i));
            }
        }
    }
}